#include "cfg_wizard.h"

#include <QDebug>
#include <QFile>

cfg_wizard::cfg_wizard()
{
    memset(&cfg_node_head, 0, sizeof(cfg_node_head));
    cfg_node_head.next   = nullptr;
    cfg_node_head.prev   = nullptr;
    cfg_node_head.child  = nullptr;
    cfg_node_head.parent = nullptr;
    cfg_node_table.clear();
}

cfg_wizard::~cfg_wizard()
{
    int i = 0;
    for (i = 0; i < cfg_node_table.length(); i++)
    {
        delete cfg_node_table.at(i);
    }
}

/**
 * \brief 将文件内容解析出来，形成链表
 * \param file_name 文件的绝对路径
 * \return int
 */
int cfg_wizard::cfg_parse(QString file_name)
{
    bool        child_flag = false;
    int         i = 0, retval = -1;
    char        type_ch;
    char       *pch    = nullptr;
    cfg_node_t *pcnode = &cfg_node_head;
    QString     fdata, cfg_data, line_data;
    QStringList lines;
    QFile       b_config(file_name);
    if (!b_config.open(QIODevice::ReadOnly))
    {
        return -1;
    }
    fdata = QString(b_config.readAll()).trimmed();
    b_config.close();

    cfg_node_head.next   = nullptr;
    cfg_node_head.prev   = nullptr;
    cfg_node_head.child  = nullptr;
    cfg_node_head.parent = nullptr;
    cfg_node_table.clear();

    //将文件以配置文本为界，分为三部分
    cfg_file_data[0] = fdata.left(fdata.indexOf("//<<<")).trimmed();
    cfg_file_data[1] = fdata.right(fdata.length() - fdata.indexOf("//<<<")).trimmed();
    cfg_file_data[1] =
        cfg_file_data[1].left(cfg_file_data[1].lastIndexOf("//</h>") + QString("//</h>").length());
    cfg_file_data[2] =
        fdata.right(fdata.length() - fdata.lastIndexOf("//</h>") - QString("//</h>").length());

    //选择配置文本进行解析
    cfg_data = cfg_file_data[1];
    if (cfg_data.length() < 20)
    {
        return -2;
    }
    //根据换行符分离文本，一行一行解析
    lines            = cfg_data.split("\n");
    cfg_node_t *ptmp = nullptr;
    QString     tmp_str, tmp_str_2;
    for (i = 0; i < lines.length(); i++)
    {
        line_data = lines.at(i);
        line_data = line_data.trimmed();
        pch       = line_data.toLatin1().data();
        //结束符，一般是 //</h> //</e>
        if (line_data.indexOf("//</") == 0)
        {
            if (pcnode->parent != nullptr)
            {
                pcnode = pcnode->parent;
            }
            child_flag = false;
        }
        else if (line_data.indexOf("//<") == 0)
        {
            //根据不同的类型，解析文本 q s o e h
            type_ch = line_data.at(4).toLatin1();
            if (type_ch == '>')
            {
                type_ch        = line_data.at(3).toLatin1();
                ptmp           = new cfg_node_t;
                ptmp->cfg_type = type_ch;
                if (type_ch == 'q')
                {
                    ptmp->q.title =
                        line_data.right(line_data.length() - line_data.indexOf(' ') - 1).trimmed();
                }
                else if (type_ch == 's')
                {
                    ptmp->s.title =
                        line_data.right(line_data.length() - line_data.indexOf(' ') - 1).trimmed();
                }
                else if (type_ch == 'o')
                {
                    ptmp->o.title =
                        line_data.right(line_data.length() - line_data.indexOf(' ') - 1).trimmed();
                    ptmp->o.param_map.clear();
                    ptmp->o.param_type = O_PARAM_NONE;
                }
                else if (type_ch == 'e')
                {
                    ptmp->e.title =
                        line_data.right(line_data.length() - line_data.indexOf(' ') - 1).trimmed();
                }
                else if (type_ch == 'h')
                {
                    ptmp->h.title =
                        line_data.right(line_data.length() - line_data.indexOf(' ') - 1).trimmed();
                }
                // 根据 h 和 e 调整节点的parent 和 child
                if ((pcnode->cfg_type == 'h' || pcnode->cfg_type == 'e') && (child_flag))
                {
                    pcnode->child = ptmp;
                    ptmp->parent  = pcnode;
                    ptmp->child   = nullptr;
                    ptmp->next    = nullptr;
                    ptmp->prev    = nullptr;
                }
                else
                {
                    pcnode->next = ptmp;
                    ptmp->next   = nullptr;
                    ptmp->prev   = pcnode;
                    ptmp->child  = nullptr;
                    ptmp->parent = pcnode->parent;
                }
                // 当前节点为 h 或者 e时，需要标记
                if ((ptmp->cfg_type == 'h' || ptmp->cfg_type == 'e'))
                {
                    child_flag = true;
                }
                pcnode = ptmp;
                // 将各个节点也备份到cfg_node_table，方便后续匹配节点title
                cfg_node_table.append(ptmp);
            }
            else if (pcnode->cfg_type == 'o')
            {
                // o 类型，需要判断参数的类型，进一步解析
                if (line_data.indexOf('=') >= 0)
                {
                    tmp_str   = line_data.left(line_data.indexOf('='));
                    tmp_str   = tmp_str.right(tmp_str.length() - tmp_str.indexOf('<') - 1);
                    tmp_str_2 = line_data.right(line_data.length() - line_data.indexOf(' ') - 1);
                    tmp_str   = tmp_str.trimmed();
                    tmp_str_2 = tmp_str_2.trimmed();
                    pcnode->o.param_type = O_PARAM_MAP;
                    pcnode->o.param_map.insert(tmp_str_2, tmp_str);
                }
                else if (line_data.indexOf('-') >= 0)
                {
                    retval = sscanf(pch, "//<%d-%d>%*s", &pcnode->o.param_range[0],
                                    &pcnode->o.param_range[1]);
                    if (retval == 2)
                    {
                        pcnode->o.param_type = O_PARAM_RANGE;
                    }
                }
            }
        }
        else if (line_data.indexOf("#define") == 0)
        {
            // define 行分为三个部分 #define var_name var_str
            type_ch = pcnode->cfg_type;
            tmp_str = line_data.right(line_data.length() - line_data.indexOf(' ') - 1);
            tmp_str = tmp_str.left(tmp_str.lastIndexOf(' '));

            tmp_str_2 = line_data.right(line_data.length() - line_data.indexOf(' ') - 1);
            tmp_str_2 = tmp_str_2.right(tmp_str_2.length() - tmp_str_2.lastIndexOf(' ') - 1);

            tmp_str   = tmp_str.trimmed();
            tmp_str_2 = tmp_str_2.trimmed();
            if (type_ch == 'q')
            {
                pcnode->q.var_name = tmp_str;
                pcnode->q.var_str  = tmp_str_2;
            }
            else if (type_ch == 's')
            {
                pcnode->s.var_name = tmp_str;
                pcnode->s.var_str  = tmp_str_2;
            }
            else if (type_ch == 'o')
            {
                pcnode->o.var_name = tmp_str;
                pcnode->o.var_str  = tmp_str_2;
            }
            else if (type_ch == 'e')
            {
                pcnode->e.var_name = tmp_str;
                pcnode->e.var_str  = tmp_str_2;
            }
        }
    }
    return 0;
}

/**
 * \brief 返回节点的title
 * \param pnode
 * \return QString
 */
QString cfg_wizard::cfg_node_title(cfg_node_t *pnode)
{
    QString title;
    title.clear();
    if (pnode == nullptr)
    {
        return title;
    }
    if (pnode->cfg_type == 'h')
    {
        title = pnode->h.title;
    }
    else if (pnode->cfg_type == 'q')
    {
        title = pnode->q.title;
    }
    else if (pnode->cfg_type == 'o')
    {
        title = pnode->o.title;
    }
    else if (pnode->cfg_type == 'e')
    {
        title = pnode->e.title;
    }
    else if (pnode->cfg_type == 's')
    {
        title = pnode->s.title;
    }
    return title;
}
